package communication;

import java.util.ArrayList;

import communication.message.*;
import communication.message.Error;
import exception.BadMessageException;

/**
 * Służy wygodnej reprezentacji wiadomości przesyłanych poprzez protokół.
 * 
 * @author Bogusław Zaręba
 */
public class Message {
	private MessageType type;
	private String msgError;
	private PlayerLogin playerLogin;
	private GameMasterLogin gameMasterLogin;
	private Response response;
	private Error error;
	private Player player;
	private ArrayList<Player> players = new ArrayList<Player>();
	private NextPlayer nextPlayer;
	private GameId gameId;
	private GameOver gameOver;
	private GameState gameState;
	private Move move;

	public Message(MessageType type) {
		this.type = type;
	}

	public MessageType getType() {
		return type;
	}

	public void setError(String error) {
		this.msgError = error;
	}
	
	//@returns String lub Error w zależności od messageType
	public Object getError() throws BadMessageException {
		switch(type) {
			case ERROR:
				return msgError;
			case LOGIN_RESPONSE:
				return error;
			default:
				throw new BadMessageException("Invalid message type.");
		}
	}

	public void setResponse(Response response) {
		this.response = response;
	}

	public void setError(Error error) {
		this.error = error;
	}

	public void setPlayerLogin(PlayerLogin pl) {
		this.playerLogin = pl;
	}

	public void setGameMasterLogin(GameMasterLogin gml) {
		this.gameMasterLogin = gml;
	}
	
	public GameMasterLogin getGameMasterLogin() {
		return this.gameMasterLogin;
	}
	
	public void setGameId(GameId gid) {
		this.gameId = gid;
	}

	public void setPlayer(Player player) {
		this.player = player;
	}

	public Player getPlayer() {
		return player;
	}
	
	public PlayerLogin getPlayerLogin() {
		return playerLogin;
	}
	
	public Response getResponse() {
		return response;
	}

	public void addPlayer(Player player) {
		this.players.add(player);
	}

	public ArrayList<Player> getPlayers() {
		return players;
	}

	public NextPlayer getNextPlayer() {
		return nextPlayer;
	}

	public void setNextPlayer(NextPlayer nextPlayer) {
		this.nextPlayer = nextPlayer;
	}

	public GameState getGameState() {
		return gameState;
	}

	public void setGameState(GameState gameState) {
		this.gameState = gameState;
	}

	public void setGameOver(GameOver gameOver) {
		this.gameOver = gameOver;
	}

	public GameOver getGameOver() {
		return gameOver;
	}

	public void setMove(Move move) {
		this.move = move;
	}

	public Move getMove() {
		return move;
	}
	public GameId getGameId()
	{
		return this.gameId;
	}

	public String toString() {
		String res = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
		if (type == MessageType.LOGOUT || type == MessageType.SERVER_SHUTDOWN)
			return res + XMLTagCreator.singleTag("message", "type", "" + type);
		res += XMLTagCreator.openTag("message", "type", "" + type) + '\n';
		switch (type) {
		case ERROR:
			res += msgError;
			break;
		case PLAYER_LOGIN:
			res += playerLogin;
			break;
		case GAME_MASTER_LOGIN:
			res += gameMasterLogin;
			break;
		case LOGIN_RESPONSE:
			res += response;
			if (!response.getAccept())
				res += "\n" + error;
			break;
		case BEGIN_GAME:
			res += gameId + "\n";//+ player;
			for(Player player : players)
				res += player + "\n";
			break;
		case GAME_STATE:
			res += gameId + "\n";
			if (getNextPlayer() != null)
				res += getNextPlayer();
			else
				res += getGameOver();
			res += "\n" + getGameState();
			break;
		case MOVE:
			res += gameId + "\n" + move;
			break;
		case THANK_YOU:
		case LEAVE_GAME:
			res += gameId;
			break;
		case PLAYER_LEFT_GAME:
			res += player + "\n" + gameId;
			break;
		case CHAMPION_LIST:
			for (Player p : players)
				res += p + "\n";
			break;
		}
		res += '\n' + XMLTagCreator.closeTag("message");
		return res;
	}
}
